#include "sys.h"
#include "usart.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
#include "encoder.h"
//#include "OpenImu.h"

//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif

//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
    int handle;
};

FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
//__use_no_semihosting was requested, but _ttywrch was
void _ttywrch(int ch)
{
    ch = ch;
}

void _sys_exit(int x)
{
    x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
    while ((USART1->SR & 0X40) == 0)
        ; //循环发送,直到发送完毕
    USART1->DR = (u8)ch;
    return ch;
}
#endif

#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15，  接收完成标志
//bit14，  接收到0x0d
//bit13~0，  接收到的有效字节数目
u16 USART_RX_STA = 0; //接收状态标记

u8 UART4_RX_BUF[UART4_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
u8 UART4_TX_BUF[UART4_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节

u8 Usarts4_Temporary_Receive[50]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
Frame_Sign Frame_Sign_usart4;

Queue ImuUart4 = {
    .ReceiveQueue = 0,
    .FrameLength = 47,
};

Queue Uart5Queue = {
    .ReceiveQueue = 0,
    .FrameLength = 30,
};

UartRecv Uart5Event = {
    .frame = {0x0d, 0x0a, 0x00, 0x5a, 0xa5, 0x00, 0x00},
    .DataBumber = 0,
    .FrameLength = 30,
    .NowData = 0,
};

void uart_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1，GPIOA时钟

    //USART1_TX   GPIOA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);          //初始化GPIOA.9

    //USART1_RX    GPIOA.10初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;    //PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);        //初始化GPIOA.10

    //Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                           //根据指定的参数初始化VIC寄存器

    //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;                                     //串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     //字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          //一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             //无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 //收发模式

    USART_Init(USART1, &USART_InitStructure);      //初始化串口1
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接受中断
    USART_Cmd(USART1, ENABLE);                     //使能串口1
}

void uart2_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);  //使能GPIOD时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //串口2时钟使能

    //USART2_TX   GPIOD.5
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    GPIO_Init(GPIOD, &GPIO_InitStructure);          //初始化GPIOA.9

    //USART2_RX    GPIOD.6初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;             //PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOD, &GPIO_InitStructure);                //初始化GPIOA.10

    //Usart2 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                           //根据指定的参数初始化VIC寄存器

    //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;                                     //串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     //字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          //一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             //无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 //收发模式

    USART_Init(USART2, &USART_InitStructure);      //初始化串口2
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启串口接受中断
    USART_Cmd(USART2, ENABLE);                     //使能串口2
}

void uart4_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能GPIOD时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); //串口2时钟使能

    USART_DeInit(UART4); //复位串口4

    //USART2_TX   GPIOD.5
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    GPIO_Init(GPIOC, &GPIO_InitStructure);          //初始化GPIOA.9

    //USART2_RX    GPIOD.6初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;            //PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOC, &GPIO_InitStructure);                //初始化GPIOA.10

    //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;                                     //串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     //字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          //一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             //无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 //收发模式

    USART_Init(UART4, &USART_InitStructure); //初始化串口2

    //Usart2 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                           //根据指定的参数初始化VIC寄存器

    USART_ClearFlag(UART4, USART_FLAG_RXNE);
    USART_Cmd(UART4, ENABLE);                     //使能串口2
    USART_ITConfig(UART4, USART_IT_RXNE, ENABLE); //开启串口接受中断
}

void uart5_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE); //使能GPIOD时钟,GPIOC时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);                        //串口2时钟使能

    USART_DeInit(UART5); //复位串口4

    //UART5_TX   GPIOD.5
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    GPIO_Init(GPIOC, &GPIO_InitStructure);          //初始化GPIOA.9

    //UART5_RX    GPIOD.6初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;             //PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOD, &GPIO_InitStructure);                //初始化GPIOA.10

    //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;                                     //串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     //字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          //一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             //无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 //收发模式

    USART_Init(UART4, &USART_InitStructure); //初始化串口2

    //Usart2 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                           //根据指定的参数初始化VIC寄存器

    USART_ClearFlag(UART5, USART_FLAG_RXNE);
    USART_Cmd(UART5, ENABLE);                     //使能串口2
    USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); //开启串口接受中断
}

void USART1_IRQHandler(void) //串口1中断服务程序
{
    u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真，则需要支持OS.
    OSIntEnter();
#endif
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
    {
        Res = USART_ReceiveData(USART1); //读取接收到的数据

        if ((USART_RX_STA & 0x8000) == 0) //接收未完成
        {
            if (USART_RX_STA & 0x4000) //接收到了0x0d
            {
                if (Res != 0x0a)
                    USART_RX_STA = 0; //接收错误,重新开始
                else
                    USART_RX_STA |= 0x8000; //接收完成了
            }
            else //还没收到0X0D
            {
                if (Res == 0x0d)
                    USART_RX_STA |= 0x4000;
                else
                {
                    USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
                    USART_RX_STA++;
                    if (USART_RX_STA > (USART_REC_LEN - 1))
                        USART_RX_STA = 0; //接收数据错误,重新开始接收
                }
            }
        }
    }
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真，则需要支持OS.
    OSIntExit();
#endif
}

void USART1_Send_Byte(unsigned char byte) //串口发送一个字节
{
    USART_SendData(USART1, byte); //通过库函数  发送数据
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET)
        ; //等待发送完成。   检测 USART_FLAG_TC 是否置1；
}

void USART2_IRQHandler(void) // 串口2中断服务函数
{
    u8 res;
    if (USART_GetITStatus(USART2, USART_IT_RXNE)) // 中断标志
    {
        res = USART_ReceiveData(USART2); // 串口2 接收
        USART_SendData(USART2, res);     // 串口2 发送
    }
}

/****
 *在MCU系统负载较重、串口收发数据频率很高、多个中断存在
 *（如同时有定时器更新中断、外部中断、DMA中断、串口接收中断）的情况下，
 * 容易出现串口溢出错误（ORE）。
 * 该错误的主要显现形式是：程序莫名卡死在串口中断之中（单片机失去响应）
*/

void UART4_IRQHandler(void) // 串口2中断服务函数
{
    static u8 DataNumber = 0; //*****添加静态变量*****/
    u8 Res;
    /**
   * 如果使能串口接收中断，那么ORE为1时也会产生中断。
   * 在应用中对ORE标志进行处理，当判断发生ORE中断的时候，
   * 我们再读一次USART_DR的值，
   * 这样如果没有新的Overrun 溢出事件发生的时候，ORE会被清除,
   * 然后程序就不会因为ORE未被清除而一直不断的进入串口中断
   */

    //没有使能USART_IT_ERR中断时，ORE中断只能使用USART_GetFlagStatus(USART1, USART_FLAG_ORE)读到
    if (USART_GetFlagStatus(UART4, USART_FLAG_ORE) != RESET)
    {
        //(void)USARTx->SR;
        //(vois)USARTx->DR; //先读SR再读DR寄存器

        Res = USART_ReceiveData(UART4); // 串口2 接收

        //USART_ClearFlag(UART4, USART_FLAG_ORE);
    }

    if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //接收到数据
    {
        //        USART_ClearITPendingBit(UART4, USART_IT_RXNE);
        Res = USART_ReceiveData(UART4); //(USART1->DR);  //读取接收到的数据

        switch (Frame_Sign_usart4.now_status)
        {
            // printf("Begining_Frame_Sign_usart3.now_status:%d\r\n",Frame_Sign_usart3.now_status);
        case Usart_Initial_number:
            if (Res == 0x55)
            {
                Frame_Sign_usart4.now_status = Usart_0D;
                Usarts4_Temporary_Receive[0] = Res;
                DataNumber++;
            }
            else
            {
                Frame_Sign_usart4.now_status = Usart_Initial_number;
                DataNumber = 0;
            }
            break;
        case Usart_0D:
            if (Res == 0x55)
            {
                Frame_Sign_usart4.now_status = Usart_0A;
                Usarts4_Temporary_Receive[1] = Res;
                DataNumber++;
            }
            else
            {
                Frame_Sign_usart4.now_status = Usart_Initial_number;
                DataNumber = 0;
            }
            break;
        case Usart_0A:
            Usarts4_Temporary_Receive[DataNumber] = Res;
            DataNumber++;
            //   printf("i_number:%d\r\n",i_number);
            if (DataNumber == 47)
            {
                if ((Usarts4_Temporary_Receive[2] == 0x7a) && (Usarts4_Temporary_Receive[3] == 0x31)) //判断包尾
                {
                    Frame_Sign_usart4.now_status = Usart_All_Tail;
                    if (!ImuJudgeCrc()) //判断收到一条完整的正确的包
                    {
                        if ((ImuUart4.ReceiveQueue * 47) < UART4_MAX_RECV_LEN) //若对列数小于20，代表队列数缓存未填满
                        {
                            for (u8 i = 0; i < 47; i++)
                            {
                                //                                UART4_RX_BUF[Receive_Queue*47+i] = Usarts4_Temporary_Receive[i] ;
                                ImuUart4.DataCache[ImuUart4.ReceiveQueue * 47 + i] = Usarts4_Temporary_Receive[i]; //收到完整一包入队
                            }
                            ImuUart4.ReceiveQueue++; //每次进入CRC这里，说明收到符合协议的数据，缓存里的待处理数据+1
                            Frame_Sign_usart4.now_status = Usart_Initial_number;
                            //    Frame_Sign_usart4.now_status = Usart_CRC;
                            DataNumber = 0;

                            //                            Uart4Time.LastTime= Uart4Time.Cnt;    //更新串口接收的当前时间，用以判断是否接收超时，是否出现通信故障      //注意要修改！！！！！
                        }
                        else //若缓存填满了，则不接收新的数据，当前收到的数据清零
                        {
                            Frame_Sign_usart4.now_status = Usart_Initial_number;
                            DataNumber = 0;
                        }
                    } //判断CRC
                    else
                    {
                        Frame_Sign_usart4.now_status = Usart_Initial_number;
                        DataNumber = 0;
                    }
                }
                else
                {
                    Frame_Sign_usart4.now_status = Usart_Initial_number;
                    DataNumber = 0;
                }
            }
            else if (DataNumber > 47)
            {
                DataNumber = 0;
                Frame_Sign_usart4.now_status = Usart_Initial_number;
            }
            else
                ;
            break;
        case Usart_Faile:
            DataNumber = 0;
            Frame_Sign_usart4.now_status = Usart_Initial_number;
            break;
        case Usart_CRC:
            if (Frame_Sign_usart4.now_status == Usart_CRC)
            {
                ;
            }
        default:
            DataNumber = 0;
            Frame_Sign_usart4.now_status = Usart_Initial_number;
            break;
            // printf("End_Frame_Sign_usart3.now_status:%d\r\n",Frame_Sign_usart3.now_status);
        }
    }
}

void Queue_Extract(Queue *queue) //从接收缓存中提取一帧数据，并更新数组
{
    if (queue->ReceiveQueue != 0)
    {
        for (u8 i = 0; i < queue->FrameLength; i++)
        {
            queue->Data[i] = queue->DataCache[i]; //把接收到的一帧数据缓存到处理区域 ，始终处理队列里的第一条数据，即数组[0]-[11]这帧
        }

        //将整个队列整体向前移动queue->FrameLength个字节    ，第一帧数据从[0]-[11]被提取出来，后面的队列向前移动
        for (u8 i = 0; i < (queue->ReceiveQueue - 1); i++)
        { //循环移动提取后的队列次数
            for (u8 a = 0; a < queue->FrameLength; a++)
            {
                queue->DataCache[i * queue->FrameLength + a] = queue->DataCache[(i + 1) * queue->FrameLength + a]; //把后一帧数据移动到前一帧
            }
        }
        //提取出来了一帧数据，则当前队列最后一帧数据补零清空
        for (u8 i = 0; i < queue->FrameLength; i++)
        {
            queue->DataCache[(queue->ReceiveQueue - 1) * queue->FrameLength + i] = 0x00; //将队列中最后一帧数据清零
        }
        queue->ProceseeReceiveQueue = queue->ReceiveQueue; //置值为1，则代表当前接收到处理事件
        queue->ReceiveQueue = queue->ReceiveQueue - 1;     //队列数减一，代表提取完了一帧数据，队列数重新赋值
    }
    else
        queue->ProceseeReceiveQueue = 0; //若当前接收对列数为0，则代表待处理事件为0
}

//清零进程数组
void ClearQueue(Queue *queue)
{
    for (u8 i = 0; i < queue->FrameLength; i++)
    {
        queue->Data[i] = 0x00; //处理完一条指令，进程数组清零
    }
}

void UART4_Send_Array(unsigned char send_array[], unsigned char num) //两个参数 一是数组(的数据) 二是数组长度1-255
{
    unsigned char i = 0; //定义一个局部变量  用来 发送字符串 ++运算
    while (i < num)
    {
        USART_SendData(UART4, send_array[i]); //通过库函数  发送数据
        while (USART_GetFlagStatus(UART4, USART_FLAG_TC) != SET)
            ; //等待发送完成。   检测 USART_FLAG_TC 是否置1；
        i++;  //值 加一
    }
}

void UART4_Send_Byte(unsigned char byte) //串口发送一个字节
{
    USART_SendData(UART4, byte); //通过库函数  发送数据
    while (USART_GetFlagStatus(UART4, USART_FLAG_TC) != SET)
        ; //等待发送完成。   检测 USART_FLAG_TC 是否置1；
}

//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u4_printf(char *fmt, ...) //...表示可变参数（多个可变参数组成一个列表，后面有专门的指针指向他），不限定个数和类型
{
    u16 i, j;
    va_list ap;                              //初始化指向可变参数列表的指针
    va_start(ap, fmt);                       //将第一个可变参数的地址付给ap，即ap指向可变参数列表的开始
    vsprintf((char *)UART4_TX_BUF, fmt, ap); //将参数fmt、ap指向的可变参数一起转换成格式化字符串，放(char*)USART3_TX_BUF数组中，其作用同sprintf（），只是参数类型不同
    va_end(ap);
    i = strlen((const char *)UART4_TX_BUF); //此次发送数据的长度
    for (j = 0; j < i; j++)                 //循环发送数据
    {
        while (USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET)
            ;                                   //循环发送,直到发送完毕
        USART_SendData(UART4, UART4_TX_BUF[j]); //把格式化字符串从开发板串口送出去
    }
}

u8 ImuJudgeCrc()
{
    return 0;
}

/**
  * @brief  串口CRC校验
  * @param  Recv：UartRecv型指针
  * @retval 解析的结果 0：成功，其他：相应的错误码
  */
int UartJudegCrc(UartRecv *Recv)
{
    int sum = 0;
    int * a=0;
    for(u8 i=0;i<Recv->FrameLength-6;i++)
    {
         sum+=Recv->Temporary_Receive[2+i];
    }
    a = (int *)&Recv->Temporary_Receive[Recv->FrameLength-6];
    if(sum == (*a))
    {
         return 0;
    }
    else
        return 1;
}



//两个参数 一是数组(的数据) 二是数组长度1-255
void UART5_Send_Array(unsigned char send_array[], unsigned char num) 
{
    unsigned char i = 0; //定义一个局部变量  用来 发送字符串 ++运算
    while (i < num)
    {
        USART_SendData(UART5, send_array[i]); //通过库函数  发送数据
        while (USART_GetFlagStatus(UART5, USART_FLAG_TC) != SET)
            ; //等待发送完成。   检测 USART_FLAG_TC 是否置1；
        i++;  //值 加一
    }
}

void UART5_IRQHandler(void) // 串口2中断服务函数
{
    // static u8 DataNumber = 0; //*****添加静态变量*****/
    u8 Res;
    if (USART_GetFlagStatus(UART5, USART_FLAG_ORE) != RESET)
    {
        Res = USART_ReceiveData(UART4); // 串口2 接收
    }
    if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) //接收到数据
    {
        //USART_ClearITPendingBit(UART4, USART_IT_RXNE);
        Res = USART_ReceiveData(UART5); //(USART1->DR);  //读取接收到的数据
        Uart5Event.NowData = Res;
        HandleUart(Uart5Event, UartJudegCrc, Uart5Queue);
    }
}

u8 HandleUart(UartRecv UartEvent, int (*handle)(UartRecv *), Queue UartQueue)
{
    switch (UartEvent.frame.now_status)
    {
    case Usart_Initial_number:
        if (UartEvent.NowData == UartEvent.frame.head_1)
        {
            UartEvent.frame.now_status = Usart_0D;
            UartEvent.Temporary_Receive[0] = UartEvent.NowData;
            UartEvent.DataBumber++;
        }
        else
        {
            UartEvent.frame.now_status = Usart_Initial_number;
            UartEvent.DataBumber = 0;
        }
        break;
    case Usart_0D:
        if (UartEvent.NowData == UartEvent.frame.head_2)
        {
            UartEvent.frame.now_status = Usart_0A;
            UartEvent.Temporary_Receive[1] = UartEvent.NowData;
            UartEvent.DataBumber++;
        }
        else
        {
            UartEvent.frame.now_status = Usart_Initial_number;
            UartEvent.DataBumber = 0;
        }
        break;
    case Usart_0A:
        UartEvent.Temporary_Receive[UartEvent.DataBumber] = UartEvent.NowData;
        UartEvent.DataBumber++;
        if (UartEvent.DataBumber == UartEvent.FrameLength)
        {
            if ((UartEvent.Temporary_Receive[UartEvent.FrameLength - 1] == UartEvent.frame.tail_2) && (UartEvent.Temporary_Receive[UartEvent.FrameLength - 2] == UartEvent.frame.tail_2)) //判断包尾
            {
                UartEvent.frame.now_status = Usart_All_Tail;
                if (!(*handle)(&UartEvent)) //判断收到一条完整的正确的包
                {
                    if ((UartQueue.ReceiveQueue * UartEvent.FrameLength) < UART4_MAX_RECV_LEN) //若对列数小于20，代表队列数缓存未填满
                    {
                        for (u8 i = 0; i < UartEvent.FrameLength; i++)
                        {
                            //UART4_RX_BUF[Receive_Queue*47+i] = Usarts4_Temporary_Receive[i] ;
                            UartQueue.DataCache[UartQueue.ReceiveQueue * UartEvent.FrameLength + i] = UartEvent.Temporary_Receive[i]; //收到完整一包入队
                        }
                        UartQueue.ReceiveQueue++; //每次进入CRC这里，说明收到符合协议的数据，缓存里的待处理数据+1
                        UartEvent.frame.now_status = Usart_Initial_number;
                        //  Frame_Sign_usart4.now_status = Usart_CRC;
                        UartEvent.DataBumber = 0;

                        // Uart4Time.LastTime= Uart4Time.Cnt;    //更新串口接收的当前时间，用以判断是否接收超时，是否出现通信故障      //注意要修改！！！！！
                    }
                    else //若缓存填满了，则不接收新的数据，当前收到的数据清零
                    {
                        UartEvent.frame.now_status = Usart_Initial_number;
                        UartEvent.DataBumber = 0;
                    }
                } //判断CRC
                else
                {
                    UartEvent.frame.now_status = Usart_Initial_number;
                    UartEvent.DataBumber = 0;
                }
            }
            else
            {
                UartEvent.frame.now_status = Usart_Initial_number;
                UartEvent.DataBumber = 0;
            }
        }
        else if (UartEvent.DataBumber > UartEvent.FrameLength)
        {
            UartEvent.DataBumber = 0;
            UartEvent.frame.now_status = Usart_Initial_number;
        }
        else
            ;
        break;

    case Usart_Faile:
        UartEvent.DataBumber = 0;
        UartEvent.frame.now_status = Usart_Initial_number;
        break;
    case Usart_CRC:
        if (UartEvent.frame.now_status == Usart_CRC)
        {
            ;
        }
    default:
        UartEvent.DataBumber = 0;
        UartEvent.frame.now_status = Usart_Initial_number;
        break;
    }
    return 1;
}

//   printf("hello world\r\n");
//   u3_printf("hello world\r\n"); //...表示可变参数（多个可变参数组成一个列表，后面有专门的指针指向他），不限定个数和类型
#endif
